﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CommonBehaviors.Actions;
using Styx;
using Styx.Logic;
using Styx.WoWInternals.WoWObjects;
using TreeSharp;

namespace Altarboy
{
    class LowLevelPriest
    {
        #region Delegates
        public delegate bool SimpleBoolReturnDelegate(object context);
        public delegate WoWUnit UnitSelectionDelegate(object context);
        #endregion


        // Current Player   
        public static LocalPlayer Me { get { return StyxWoW.Me; } }

        public static Composite Target()
        {
            return new PrioritySelector(
                 new Decorator(ret => AltarboySettings.Instance.EnableTargeting,
                     new PrioritySelector(

                         //Multidot. (Just shadow word pain at this level).
                          new Decorator(
                            ret => (
                                //lets keep the range to within 25 yards of the tank so its possible for them to keep some kinda aggro.
                                AltarboySettings.Instance.EnableMultiDotTargeting &&
                                TargetManager.NumOfHostileWithinRange(Me, 40) > 1
                            ),
                            new PrioritySelector(
                                
                                //Dot any other targets next
                                new Decorator(ret =>
                                    TargetManager.DetectHostileTargets(40).Any(TargetNeedsMultiDot),
                                    new TreeSharp.Action(delegate { TargetManager.DetectHostileTargets(40).First(TargetNeedsMultiDot).Target(); })
                                )

                            )

                        ),
                      
                      //Select the target that is closest.
                      new Decorator(ret => TargetManager.DetectHostileTargets(40).Any(), 
                           new TreeSharp.Action(delegate {
                            TargetManager.DetectHostileTargets(40).OrderBy( unit => unit.CurrentHealth).First().Target();
                           })  
                       ),

                      new ActionAlwaysSucceed()
                      )
                 )
            );
        }

        public static Composite Pull()
        {
            return new PrioritySelector (AltarboyComposites.CastSpell("Smite",
                ret => (true), TargetManager.ActiveTarget)
            );
        }

        public static Composite Combat()
        {
            return new PrioritySelector(
               
                // AltarboyComposites.HealSelf(), 

                new Sequence(
                    //Select a target
                    Target(),

                    //Then kill it. (No AOE Here Really)
                   SingleTargetDps()
                )
            );

        }

        private static Composite SingleTargetDps()
        {
            //Never Attack Anything That we shouldnt
            return new Decorator(
                ret => TargetManager.ShouldAttack(TargetManager.ActiveTarget),
                     new PrioritySelector(
                       new Decorator(ret => Me.IsMoving, MovementDps()),
                       new Decorator(ret => !Me.IsMoving, StationaryDps())
                      )
                );
        }

        private static Composite StationaryDps()
        {
             return new Sequence(
            
                //this is the stationary composite, so it shouldn't be an issue to face the target.
                new TreeSharp.Action(delegate { if (!Me.IsMoving) { TargetManager.ActiveTarget.Face(); } }),

               new PrioritySelector(
                    AltarboyComposites.CastSpell("Shadow Word: Pain", ret => (
                        AuraManager.GetAuraTimeLeft("Shadow Word: Pain", TargetManager.ActiveTarget, true).TotalSeconds <= .4),
                    TargetManager.ActiveTarget),
                    AltarboyComposites.CastSpell("Mind Blast", ret => (true), TargetManager.ActiveTarget),
                    AltarboyComposites.CastSpell("Smite", ret => (true), TargetManager.ActiveTarget),
                    AltarboyComposites.CreateUseWand(),
                    new TreeSharp.Action(ret => Me.ToggleAttack())
              )
          );
        }

        private static Composite MovementDps()
        {
            return new PrioritySelector(
                
                AltarboyComposites.CastSpell("Shadow Word: Pain", ret => (
                    AuraManager.GetAuraTimeLeft("Shadow Word: Pain", TargetManager.ActiveTarget, true).TotalSeconds <= .4)
                , TargetManager.ActiveTarget)

            );
        }
        
        #region Conditionals
        private static Boolean TargetNeedsMultiDot(WoWUnit target)
        {
            return target.Distance2D <= 40 && 
                target.InLineOfSight &&
                AuraManager.GetAuraTimeLeft("Shadow Word: Pain", target, true).TotalSeconds < 1.5;
        }

        #endregion
    }
}
